//记录Promise的三种状态
const PENDING = 'pending'
const FULLFILLED = 'fullfilled'
const REJECTED = 'rejected'

/**
 * 运行一个微队列任务
 * 把传递的函数放到微队列中
 * @param {Function} callback 
 */
function runMicroTask(callback){
    // 判断node环境
    if(process && process.nextTick){//node环境的process.nextTick就是一个微队列函数
        process.nextTick(callback)
    }else if(MutationObserver){//浏览器环境
        const p = document.createElement('p');
        const observer = new MutationObserver(callback);
        observer.observe(p,{
            childList:true,
        })
        p.innerHTML = '1';
    }
}

class MyPromise{

   /**
    * 创建一个Promise
    * @param {Function} executor 任务执行器，立即执行
    */ 
   constructor(executor){
    this._state = PENDING
    this._value = undefined
    this._handlers = []
    try{
        executor(this._resolve.bind(this),this._reject.bind(this))
    }catch(error){
        this._reject(error)
    }
    
   }

   /**
    * 向处理队列中添加一个函数
    * @param {Function} executor 添加的函数
    * @param {String} state 该函数什么状态下执行
    * @param {Function} resolve 让then函数返回的promise成功
    * @param {Function} reject 让then函数返回的promise失败
    */
   _pushHandler(executor,state,resolve,reject){
    this._handlers.push({
        executor,state,resolve,reject
    })
   }

   /**
    * 
    * @param {String} newState 新状态
    * @param {*} value 相关数据
    */
   _changeState(newState,value){
    if(this._state!==PENDING){
        //目前状态已更改
        return
    }
    this._state = newState;
    this._value = value
   }
   /**
    * 标记当前任务完成
    * @param {any} data 任务完成的相关数据
    */
   _resolve(data){
    //改变状态和数据
    this._changeState(FULLFILLED,data);
   }
   /**
    * 标记当前任务失败
    * @param {any} reason 任务失败的相关数据
    */
   _reject(reason){
    //改变状态和数据
    this._changeState(REJECTED,reason);
   }
   /**
    * PromiseA+规范的then函数
    * @param {Function} onFullFilled 
    * @param {Function} onRejected 
    */
   then(onFullFilled,onRejected){//1.注册任务
    
    return new MyPromise((resolve,rejected)=>{
        this._pushHandler(onFullFilled,FULLFILLED,resolve,rejected)
        this._pushHandler(onRejected,REJECTED,resolve,rejected)
    })  
   }

}
const  p = new MyPromise((resolve,reject)=>{
    setTimeout(() => {
        resolve(1)
        console.log(p);
    }, 1000);
})
p.then(
    function A1(){},
    function A2(){},
)
p.then(
    function B1(){},
    function B2(){},
)